package com.miya.lib_common.networking;

import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.miya.lib_common.BuildConfig;
import com.miya.lib_common.utils.UtilsFactory;

import org.jdeferred2.Deferred;
import org.jdeferred2.Promise;
import org.jdeferred2.android.AndroidDeferredObject;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringBufferInputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

/**
 * Networking
 */
public class Networking {
    private static Networking instance;

    public static Networking getInstance() {
        if (instance == null) instance = new Networking();
        return instance;
    }

    public static final String RM_GET = "GET";
    public static final String RM_POST = "POST";

    protected HttpsURLConnection buildHttps(String u) throws IOException {
        HttpsURLConnection httpsUrl;
        URL url = new URL(u);
        HttpsTrustTool.getInstance().trustAll();
        httpsUrl = (HttpsURLConnection) url.openConnection();
        return httpsUrl;
    }

    public <T> Promise<T, Throwable, Void> requestGet(String url, Class<T> tClass) {
        return requestGet(5000, url, tClass);
    }

    public <T> Promise<T, Throwable, Void> requestGet(int timeOut, String url, Class<T> tClass) {
        Deferred<T, Throwable, Void> deferred = new AndroidDeferredObject<>();
        UtilsFactory.getInstance().runOnAsync(new Runnable() {
            @Override
            public void run() {
                HttpsURLConnection httpsURLConnection = null;
                try {
                    httpsURLConnection = buildHttps(url);
                    httpsURLConnection.setRequestMethod(RM_GET);
                    httpsURLConnection.setConnectTimeout(timeOut);
                    httpsURLConnection.setReadTimeout(timeOut);
                    if (httpsURLConnection.getResponseCode() == HttpsURLConnection.HTTP_OK) {
                        InputStream inputStream = httpsURLConnection.getInputStream();
                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
                        int len = 0;
                        byte[] bytes = new byte[2048];
                        while ((len = inputStream.read(bytes)) != -1) {
                            bos.write(bytes, 0, len);
                        }
                        String responseStr = bos.toString();
                        if (BuildConfig.DEBUG)
                            Log.i("networking", "ResponseBody: "+httpsURLConnection.getRequestMethod()+" "+httpsURLConnection.getResponseMessage()+ "\n"+ responseStr);

                        inputStream.close();
                        bos.close();
                        if (TextUtils.isEmpty(responseStr)) {
                            deferred.reject(new IOException("response is null"));
                        } else {
                            T t = new Gson().fromJson(responseStr, tClass);
                            deferred.resolve(t);
                        }
                    } else {
                        deferred.reject(new IOException(httpsURLConnection.getResponseMessage()));
                    }
                } catch (IOException e) {
                    deferred.reject(e);
                }
            }
        });
        return deferred.promise();
    }


    public <T> Promise<T, Throwable, Void> requestPost(String url, Class<T> tClass) {
        return requestPost(5000, url, tClass);
    }

    public <T> Promise<T, Throwable, Void> requestPost(int timeOut, String url, Class<T> tClass) {
        Deferred<T, Throwable, Void> deferred = new AndroidDeferredObject<>();
        UtilsFactory.getInstance().runOnAsync(new Runnable() {
            @Override
            public void run() {
                HttpsURLConnection httpsURLConnection = null;
                try {
                    httpsURLConnection = buildHttps(url);
                    httpsURLConnection.setRequestMethod(RM_POST);
                    httpsURLConnection.setConnectTimeout(timeOut);
                    httpsURLConnection.setReadTimeout(timeOut);
                    if (httpsURLConnection.getResponseCode() == HttpsURLConnection.HTTP_OK) {
                        InputStream inputStream = httpsURLConnection.getInputStream();
                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
                        int len = 0;
                        byte[] bytes = new byte[2048];
                        while ((len = inputStream.read(bytes)) != -1) {
                            bos.write(bytes, 0, len);
                        }
                        String responseStr = bos.toString();
                        if (BuildConfig.DEBUG)
                            Log.i("networking", "ResponseBody: "+httpsURLConnection.getRequestMethod()+" "+httpsURLConnection.getResponseMessage()+ "\n"+ responseStr);

                        inputStream.close();
                        bos.close();
                        if (TextUtils.isEmpty(responseStr)) {
                            deferred.reject(new IOException("response is null"));
                        } else {

                            T t = new Gson().fromJson(responseStr, tClass);
                            deferred.resolve(t);
                        }
                    } else {
                        deferred.reject(new IOException(httpsURLConnection.getResponseMessage()));
                    }
                } catch (IOException e) {
                    deferred.reject(e);
                }
            }
        });
        return deferred.promise();
    }


}
